《CMake实践》笔记+实践记录,包括一些书中的坑

您所在的位置:网站首页 cmake 书籍 《CMake实践》笔记+实践记录,包括一些书中的坑

《CMake实践》笔记+实践记录,包括一些书中的坑

2023-09-02 21:18| 来源: 网络整理| 查看: 265

这本教程很短,总共只有47页,然而下来共花费约8个小时。其中,阅读+例程实践共花费(3.4日 - 3.10日)共花费5小时21分钟;整理笔记+发博客(3.11日和3.29日)共花费2小时25分钟 。

放一张阅读时间记录图。 阅读时间记录 做笔记总结真的太耗时了,而且自己很抗拒。由上图知,假如说只在文档上做标记,确实很简单,用5天的时间就看完了。然而起后便扔下不管了,直到今天快月底了才不得不写一篇总结,努力往上爬真他妈难啊。。。。

阅读完的时候,自己的任务也就结束了,可这样总感觉不是自己的东西,不如整理一下,吸收其中自己认为最有用的东西,这样也能极大的减轻自己的记忆负担。

当然,与自己使用marddown语法不熟练和MarkdownPad 2这个软件不好用也有关系,导致自己排版也花费了好多精力,下次直接在csdn里的markdown记录就行了,不要用MarkdownPad 2,别人觉得好用了不一定适合自己!!!

记笔记的教训总结一下:

最后总结的时候,不要事无巨细都想记录下来。只记录自己觉得最有用的就行了,想象如果只让你记录三点你会记录哪些,以此来帮助自己筛选重要的东西。工具用好,以后就在csdn里面记录了,统一工具也避免不必要的麻烦!

笔记从第三章开始,包括一些文档里的错误所造成的坑!

三 初试 cmake – cmake 的 helloworld

遇到的坑 不要直接复制原文中代码,原文中代码""用的是中文字符,所以编译会出错,而且不好发现

cmake … 之后make

首先注意的是,当你定义了工程名时,cmake会预定义一些带有工程名的cmake变量。 PROJECT (HELLO) HELLO_BINARY_DIR HELLO_SOURCE_DIR PROJECT_BINARY_DIR PROJECT_SOURCE_DIR 如果是内部编译,就相当于 PROJECT_SOURCE_DIR 也就是 工程代码所在目录,如果是外部编译,**指的是外部编译所在目录**

指令是大小写无关的,参数和变量是大小写相关的 ; IF中使用变量名,不需要${变量名}

清理工程 make clean

内部构建和外部构建,cmake强烈推荐的是外部构建(out-of-source build)

内部构建就是在工程主目录下,也就是CMakeLists.txt所在的文件夹下编译; 而外部构建不是在此目录下编译的。一般是新建一个build文件夹,在此文件夹下cmake ..,生成makefile文件,然后再make编译。 四 更好一点的 Hello World

工程中多了src目录存放源文件。

需要为任何子目录建立一个 CMakeLists.txt PROJECT(HELLO) ADD_SUBDIRECTORY(src bin) 应该把这两条指令写在工程的 CMakeLists.txt 还是 src 目录下的CMakeLists.txt? 把握一个简单的原则,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY, 如果需要改变目标存放路径,就在哪里加入上述的定义

如何安装文件 如果你希望使用 CMAKE_INSTALL_PREFIX 来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是 ${CMAKE_INSTALL_PREFIX}/。 安装的需要有两种,一种是从代码编译后直接 make install 安装,一种是打包时的指定目录安装。

make和make install 的区别: make是在本地编译,编译所产生的文件在编译的文件夹里; make install则把编译产生的文件(如库文件,可执行文件,以及cmake指定的要安装的文件)安装到某个目录(一般是系统目录),这样其他程序就可以调用编译的这些东西了。

安装需要这个变量:CMAKE_INSTALL_PREFIX ,格式如下: cmake -DCMAKE_INSTALL_PREFIX=/usr . 即生成安装到/usr目录的make file

INSTALL一共有如下几种形式:

目标文件的安装: INSTALL(TARGETS targets... [ARCHIVE|LIBRARY|RUNTIME] [DESTINATION dirname] [PERMISSIONS permissions...] [...]) 如INSTALL(TARGETS myrun mylib mystaticlib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION libstatic ) 可执行二进制 myrun 安装到 C M A K E I N S T A L L P R E F I X / b i n 目 录 动 态 库 l i b m y l i b 安 装 到 {CMAKE_INSTALL_PREFIX}/bin 目录 动态库 libmylib 安装到 CMAKEI​NSTALLP​REFIX/bin目录动态库libmylib安装到{CMAKE_INSTALL_PREFIX}/lib 目录 静态库 libmystaticlib 安装到${CMAKE_INSTALL_PREFIX}/libstatic 目录 特别注意的是你不需要关心 TARGETS 具体生成的路径,只需要写上 TARGETS 名称就可以 了。普通文件的安装 INSTALL(FILES files... DESTINATION [PERMISSIONS permissions...]) 非目标文件的可执行程序安装(比如脚本之类): INSTALL(PROGRAMS files... DESTINATION [PERMISSIONS permissions...]) 脚本安装后注意设置权限为: OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限目录的安装 INSTALL(DIRECTORY dirs... DESTINATION [FILE_PERMISSIONS permissions...]) DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意: abc 和 abc/有很大的区别。 如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾, 代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。安装时CMAKE脚本的执行: INSTALL([[SCRIPT ] [CODE ]] [...]) 五 静态库与动态库构建

本章主要讲了如何编译动态库/静态库,并安装库文件与头文件(.h)到系统目录中,以便其他程序调用这个库. 动态库是 .so文件,又叫共享库,静态库是.a文件。

如何通过 ADD_LIBRARY 指令构建动态库和静态库;如何通过 SET_TARGET_PROPERTIES 同时构建同名的动态库和静态库;如何通过 SET_TARGET_PROPERTIES 控制动态库版本;最后将头文件和共享库安装到系统目录/usr/lib 和/usr/include/hello

所有的添加目录操作ADD_SUBDIRECTORY(lib)都在最外层的CMakeLists.txt中添加,且目录都是相对最外层的,不是绝对路径。

六 如何使用外部共享库和头文件

main.c中包含头文件hello.h会失败,因为hello.h 位于/usr/include/hello 目录中,并没有位于系统标准的头文件路径(系统标准头文件路径在/usr/include,其子目录hello并不是)

#include int main() { HelloFunc(); return 0; }

所以需要引入头文件搜索路径 INCLUDE_DIRECTORIES(/usr/include/hello) 此时编译还是会失败,因为没有链接到hello库文件。 所以需为 target 添加共享库 讲了两个指令 LINK_DIRECTORIES(directory1 directory2 ...) 添加非标准的共享库搜索路径,这个对应上面的INCLUDE_DIRECTORIES,本例没有用到此指令。 TARGET_LINK_LIBRARIES(main hello)

七 cmake 常用变量和常用环境变量

需要注意cmake变量分为隐式定义和显式定义两种。可以理解为隐式变量就是cmake自动生成的,直接可以用的。 隐式定义如PROJECT 指令,他 会隐式的定义_BINARY_DIR 和_SOURCE_DIR 两个变 量。显式定义如 SET 指令,就可以构建一个自定义变量了。

八 cmake 常用指令

主要讲了基本指令,INSTALL指令,FIND_指令(如FIND_FILE,FIND_LIBRARY,FIND_PATH,FIND_PACKAGE)

基本指令 ADD_DEPENDENCIES,定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。 CMAKE_MINIMUM_REQUIRED 比如 CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR) 如果 cmake 版本小与 2.5,则出现严重错误,整个过程中止。FIND指令 找到目标之后都会存到VAR变量里面。 FIND_FILE( name1 path1 path2 …) FIND_LIBRARY( name1 path1 path2 …) FIND_PATH( name1 path1 path2 …) FIND_PROGRAM( name1 path1 path2 …) FIND_PACKAGE() 九 复杂的例子:模块的使用和自定义模块

FIND_PACKAGE(CURL) 这句指令会自动产生一些变量,如CURL_FOUND CURL_INCLUDE_DIR CURL_LIBRARY,每一个模块都会定义以下几个变量:

_FOUND_INCLUDE_DIR or _INCLUDES_LIBRARY or _LIBRARIES

FIND_PACKAGE([package name] REQUIRED) REQUIRED 参数,其含义是指这个共享库是否是工程必须的,如果使用了这个参数,说明这个链接库是必备库,如果找不到这个链接库,则工程不能编译。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3